#include "cxipopupbox.h"
#include "controls/flowlayout/cxiflowlayout.h"

#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFrame>
#include <QLabel>
#include <QDebug>
#include <QApplication>
#include <QScreen>
#include <QGraphicsOpacityEffect>
#include <QLayoutItem>

CxiPopupBox::CxiPopupBox(QWidget* parent)
	: QWidget(parent),
	  m_label(new QLabel(this)),
	  m_popup(nullptr),
	  m_popupContainer(nullptr),
	  m_flow(nullptr),
	  m_hideTimer(new QTimer(this)),
	  m_fadeAnim(new QPropertyAnimation(this))
{
	auto* lay = new QHBoxLayout(this);
	lay->setContentsMargins(6, 2, 6, 2);
	lay->setSpacing(4);
	m_label->setText("+0");
	m_label->setAlignment(Qt::AlignCenter);
	lay->addWidget(m_label);

	setCursor(Qt::PointingHandCursor);
	setAttribute(Qt::WA_Hover, true);

	m_hideTimer->setSingleShot(true);
	m_hideTimer->setInterval(180);
	connect(m_hideTimer, &QTimer::timeout, this, [this]() {
		hidePopupIfNeeded();
	});

	QWidget* topWindow = parent ? parent->window() : nullptr;
	m_popup = new QFrame(topWindow, Qt::FramelessWindowHint | Qt::Tool);
	m_popup->setAttribute(Qt::WA_ShowWithoutActivating);
	m_popup->setAttribute(Qt::WA_TranslucentBackground);
	m_popup->setWindowFlag(Qt::WindowStaysOnTopHint);

	m_popupContainer = new QWidget(m_popup);
	m_flow = new CxiFlowLayout(m_popupContainer, 6, 6, 6);
	m_popupContainer->setLayout(m_flow);
	// 给流式布局的容器加一个固定大小和边框，方便调试布局范围
	m_popupContainer->setFixedSize(200, 200);

	auto* popupLay = new QVBoxLayout(m_popup);
	popupLay->setContentsMargins(8, 8, 8, 8);
	popupLay->setSpacing(4);
	popupLay->addWidget(m_popupContainer);

	m_popup->hide();

	auto* effect = new QGraphicsOpacityEffect(m_popup);
	m_popup->setGraphicsEffect(effect);
	m_fadeAnim->setTargetObject(effect);
	m_fadeAnim->setPropertyName("opacity");
	m_fadeAnim->setDuration(140);
	m_fadeAnim->setStartValue(0.0);
	m_fadeAnim->setEndValue(1.0);

	m_popup->installEventFilter(this);
}

void CxiPopupBox::setCount(int count)
{
	m_label->setText(QString("+%1").arg(count));
}


void CxiPopupBox::enterEvent(QEvent* ev)
{
	QWidget::enterEvent(ev);
	m_hideTimer->stop();
	showPopupAtProperPos();
}

void CxiPopupBox::leaveEvent(QEvent* ev)
{
	QWidget::leaveEvent(ev);
	m_hideTimer->start();
}

void CxiPopupBox::showPopupAtProperPos()
{
	if (!m_popup) return;

	QPoint gp = mapToGlobal(QPoint(0, height() + 6));

#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
	QRect screenRect = screen() ? screen()->availableGeometry() : QApplication::primaryScreen()->availableGeometry();
#else
	QRect screenRect = QApplication::desktop()->availableGeometry(this);
#endif

	m_popup->adjustSize();
	QSize ps = m_popup->sizeHint();
	if (gp.x() + ps.width() > screenRect.right()) {
		gp.setX(screenRect.right() - ps.width() - 8);
	}
	if (gp.y() + ps.height() > screenRect.bottom()) {
		gp = mapToGlobal(QPoint(0, -ps.height() - 6));
	}

	m_popup->move(gp);
	m_popup->show();

	m_fadeAnim->stop();
	m_fadeAnim->setDirection(QPropertyAnimation::Forward);
	m_fadeAnim->start();
}

void CxiPopupBox::hidePopupIfNeeded()
{
	// 只有当鼠标既不在本体也不在 popup 上才隐藏
	if (!this->underMouse() && (m_popup == nullptr || !m_popup->underMouse())) {
		if (m_popup && m_popup->isVisible()) {
			// 可选：做一个淡出动画后 hide（这里直接 hide 更稳）
			m_fadeAnim->setDirection(QPropertyAnimation::Backward);
			m_popup->hide();
		}
	}
}

bool CxiPopupBox::eventFilter(QObject* watched, QEvent* event)
{
	if (watched == m_popup) {
		if (event->type() == QEvent::Enter) {
			m_hideTimer->stop();
		} else if (event->type() == QEvent::Leave) {
			m_hideTimer->start();
		}
	}
	return QWidget::eventFilter(watched, event);
}
void CxiPopupBox::addTag(QWidget* tag)
{
	m_flow->addWidget(tag);
}
void CxiPopupBox::clearTags()
{
	if (!m_flow)
		return;

	QLayoutItem* item = nullptr;
	while ((item = m_flow->takeAt(0)) != nullptr)
	{
		if (QWidget* w = item->widget())
		{
			// 只移除，不删除（因为这些 tag 的生命周期由外部管理）
			w->setParent(nullptr);
			w->hide();  // 隐藏以免干扰布局
		}
		delete item;  // 删除布局项本身
	}

	m_popupContainer->adjustSize();
	m_popup->adjustSize();
}
